package com.easylinkin.linkappapi.powerdistribution.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.easylinkin.linkappapi.common.utils.DateUtil;
import com.easylinkin.linkappapi.elasticsearch.entity.ESconfig;
import com.easylinkin.linkappapi.elasticsearch.entity.EsQuerymodel;
import com.easylinkin.linkappapi.elasticsearch.service.IEService;
import com.easylinkin.linkappapi.openapi.service.OpenApiDataVService;
import com.easylinkin.linkappapi.powerdistribution.entity.DistributionElectricPrice;
import com.easylinkin.linkappapi.powerdistribution.entity.DistributionElectricPriceConfig;
import com.easylinkin.linkappapi.powerdistribution.entity.DistributionElectricPriceConfigTime;
import com.easylinkin.linkappapi.powerdistribution.entity.ElectricityAnalysisParam;
import com.easylinkin.linkappapi.powerdistribution.mapper.DistributionElectricPriceMapper;
import com.easylinkin.linkappapi.powerdistribution.service.ElectricityAnalysisService;
import com.google.common.util.concurrent.AtomicDouble;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.support.IndicesOptions;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.script.Script;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramInterval;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

/**
 * @program: linkapp-group-cloud
 * @description: 电量分析
 * @author: chenkaixuan
 * @create: 2021-09-17 18:04
 */
@Slf4j
@Service
public class ElectricityAnalysisServiceImpl implements ElectricityAnalysisService {
    private ESconfig eSconfig;

    @Autowired
    public void setESconfig(ESconfig eSconfig) {
        this.eSconfig = eSconfig;
    }

    @Resource
    DistributionElectricPriceMapper distributionElectricPriceMapper;
    @Resource
    IEService realService;

    @Override
    public Map<String, Map<String, Object>> energyStatisticsByDeviceCodeEs(EsQuerymodel esQuerymodel) {

        return null;
    }

    @Override
    public Map<String,Object>  energySameProcessing(ElectricityAnalysisParam electricityAnalysisParam) throws IOException {
        Assert.notNull(electricityAnalysisParam.getCabinetId(), "cabinetId 不能为空");
        Assert.notNull(electricityAnalysisParam.getDeviceCode(), "deviceCode 不能为空");
        Assert.notNull(electricityAnalysisParam.getQueryStartDate(), "queryStartDate 不能为空");
        Assert.notNull(electricityAnalysisParam.getQueryEndDate(), "queryEndDate 不能为空");
        Assert.notNull(electricityAnalysisParam.getType(), "type 不能为空");
        //配置查询参数
        EsQuerymodel esQuerymodel = new EsQuerymodel();
        esQuerymodel.setAttributeIdentifiers(Arrays.asList("positive_active_energy"));
        esQuerymodel.setCurrentBeginTime(electricityAnalysisParam.getQueryStartDate());
        esQuerymodel.setCurrentEndTime(electricityAnalysisParam.getQueryEndDate());
        esQuerymodel.setDeviceCodeList(Arrays.asList(electricityAnalysisParam.getDeviceCode()));
        // 1 周 2月 3自定义 4年 5日
        esQuerymodel.setMomStatisticKind(electricityAnalysisParam.getType());
        if(electricityAnalysisParam.getType() == 0){
            return energyStatisticsByDeviceCodeEs(electricityAnalysisParam,esQuerymodel);
        }else{
            return energyStatisticsByDeviceCode(esQuerymodel);
        }
    }

    /***
     * 查询两次做环比
     * @param esQuerymodel
     * @return
     */
    private HashMap<String, Object> energyStatisticsByDeviceCode(EsQuerymodel esQuerymodel){
        Map<String, Object> newMap = realService.energyStatisticsByDeviceCode(esQuerymodel);

        Date currentBeginTime = esQuerymodel.getCurrentBeginTime();
        Date currentEndTime = esQuerymodel.getCurrentEndTime();

        Calendar  calendarStart = new GregorianCalendar();
        calendarStart.setTime(currentBeginTime);
        Calendar  calendarEnd = new GregorianCalendar();
        calendarEnd.setTime(currentEndTime);
        // 1 周 2月 3自定义 4年 5日
        if(esQuerymodel.getMomStatisticKind() == 5){
            calendarStart.add(Calendar.DATE,-1);
            calendarEnd.add(Calendar.DATE,-1);
        }else if(esQuerymodel.getMomStatisticKind() == 2){
            //设置为一号
            calendarStart.set(Calendar.DATE, 1);
            //减一天
            calendarStart.add(Calendar.MONTH, -1);

            calendarEnd.set(Calendar.DATE, 1);
            calendarEnd.add(Calendar.DATE, -1);
        }else{
            calendarStart.set(Calendar.MONTH, 0);
            calendarStart.set(Calendar.DATE, 1);
            calendarStart.add(Calendar.YEAR, -1);

            calendarEnd.set(Calendar.MONTH, 0);
            calendarEnd.set(Calendar.DATE, 1);
            calendarEnd.add(Calendar.DATE, -1);
        }
        currentBeginTime=calendarStart.getTime();
        currentEndTime=calendarEnd.getTime();
        esQuerymodel.setCurrentBeginTime(currentBeginTime);
        esQuerymodel.setCurrentEndTime(currentEndTime);
        Map<String, Object> oldMap = realService.energyStatisticsByDeviceCode(esQuerymodel);

        HashMap<String, Object> resultMap = new HashMap<>(4);
        resultMap.put("newMap", newMap);
        resultMap.put("oldMap", oldMap);
        return resultMap;
    }

    /***
     * 分时用电
     * @param electricityAnalysisParam
     * @return
     * @throws IOException
     */
    public HashMap<String, Object> energyStatisticsByDeviceCodeEs(ElectricityAnalysisParam electricityAnalysisParam,EsQuerymodel esQuerymodel) throws IOException {

        DistributionElectricPrice electricPrice = distributionElectricPriceMapper.findAllByCabinetId(electricityAnalysisParam.getCabinetId());
        if (electricPrice == null) {
            return null;
        }
        //电价方案-> 分时用电-> 时间
        @Valid List<DistributionElectricPriceConfig> distributionElectricPriceConfigList = electricPrice.getDistributionElectricPriceConfigList();
        if (distributionElectricPriceConfigList == null || distributionElectricPriceConfigList.size() <= 0) {
            return null;
        }
        int startmonth = electricityAnalysisParam.getQueryStartDate().getMonth()+1;
        int endmonth=electricityAnalysisParam.getQueryEndDate().getMonth()+1;
        //提取分时数据
        distributionElectricPriceConfigList=distributionElectricPriceConfigList.stream()
                .filter(m->m.getType()!= null && m.getType().equals(0))
                .filter(m -> {
            if (m.getMonth().indexOf(",") == -1) {
                return false;
            }
            List<Integer> jsonArray = JSONArray.parseArray(m.getMonth(), Integer.class);
            for (Integer month : jsonArray) {
                if (month < startmonth || month > endmonth) {
                    continue;
                }
                return true;
            }
            return false;
        }).collect(Collectors.toList());
        if (distributionElectricPriceConfigList == null || distributionElectricPriceConfigList.size() <= 0) {
            return null;
        }
        //开始查询
        SearchResponse searchResponse = energyStatisticsByDeviceCodeEs(esQuerymodel, 0, 9999, distributionElectricPriceConfigList);
        TreeMap<Long, Double> resultHashMap = new TreeMap<>();
        //游标查询返回ID
        String scrollId = null;
        scrollId = getEsDateAnalysis(searchResponse, resultHashMap);
        while (true) {
            if (scrollId == null) {
                break;
            }
            searchResponse = realService.getScrollData(scrollId);
            scrollId = getEsDateAnalysis(searchResponse, resultHashMap);
        }
        if(resultHashMap == null || resultHashMap.size() <=0){
            return null;
        }
        String format="yyyy-MM-dd";
        //把对象数据、数进一步解析并处理
        HashMap<String, HashMap<String, List<Double>>>  dataAnalysisAndHandler = getDataAnalysisAndHandler(resultHashMap, distributionElectricPriceConfigList,format);
        //log.info("打印对象:"+JSONObject.toJSONString(dataAnalysisAndHandler));
        //补齐
        getHourConllect(dataAnalysisAndHandler, electricityAnalysisParam.getQueryStartDate(),electricityAnalysisParam.getQueryEndDate(),format);
        //能耗计算
        HashMap<String, Object> resultMap = calculationEnergy(dataAnalysisAndHandler,format);
        //log.info("打印对象:"+JSONObject.toJSONString(resultMap));
        return resultMap;
    }

    /***
     * 把对象数据、数进一步解析并处理
     * @param resultHashMap
     * @param distributionElectricPriceConfigList
     */
    private HashMap<String, HashMap<String, List<Double>>> getDataAnalysisAndHandler(TreeMap<Long, Double> resultHashMap, List<DistributionElectricPriceConfig> distributionElectricPriceConfigList,String format) {
        //map->图表,总计
        //图表-> 日期，尖、峰平谷->数值
        //总计->尖、峰平谷
        //
        if (distributionElectricPriceConfigList == null || distributionElectricPriceConfigList.size() <= 0) {
            return null;
        }
        //key 天，value：key 类型，电量刻度
        HashMap<String, HashMap<String, List<Double>>> monthDateMap = new HashMap<>(9);
        //循环es值
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format);
        resultHashMap.entrySet().stream().forEach(m -> {
            LocalDateTime dateTime = LocalDateTime.ofEpochSecond(m.getKey() / 1000, 0, ZoneOffset.ofHours(8));
            //获取天
            String dayValue = dateTime.format(formatter);
            LocalTime localTime = dateTime.toLocalTime();
            HashMap<String, List<Double>> configTimeMap = monthDateMap.get(dayValue);
            log.info("计算能耗时间:"+dayValue+" "+localTime);
            if(configTimeMap == null){
                configTimeMap=new HashMap<>(24);
            }
            //循环匹配
            HashMap<String, List<Double>> finalConfigTimeMap = configTimeMap;
            final boolean[] falg = {false};
            distributionElectricPriceConfigList.stream().forEach(config -> {
                //添加一次不再添加
                if(falg[0]){
                    return;
                }
                //获取分时通电配置
                @Valid List<DistributionElectricPriceConfigTime> distributionElectricPriceConfigTimeList = config.getDistributionElectricPriceConfigTimeList();
                if (distributionElectricPriceConfigTimeList == null || distributionElectricPriceConfigTimeList.size() <= 0) {
                    return;
                }
                //匹配分时用电，看当前数据，落在那个槽上
                distributionElectricPriceConfigTimeList.stream().forEach(configTime -> {
                    if(falg[0]){
                        return;
                    }
                    if (localTime.isAfter(configTime.getStartTime()) && localTime.isBefore(configTime.getEndTime())) {
                        String timeKey = configTime.getStartTime() + "," + configTime.getEndTime() + "," + configTime.getType();
                        //add进入容器
                        List<Double> doubles = finalConfigTimeMap.get(timeKey);
                        if (doubles == null) {
                            doubles = new ArrayList<>();
                        }
                        doubles.add(m.getValue());
                        finalConfigTimeMap.put(timeKey, doubles);
                        falg[0] =true;
                    }
                });
            });
            //保存数值
            monthDateMap.put(dayValue, configTimeMap);
        });
        return monthDateMap;
    }

    /***
     *  计算能耗
     * @param dataMap
     */
    private HashMap<String, Object> calculationEnergy(HashMap<String, HashMap<String, List<Double>>> dataMap,String format) {
        if (dataMap == null || dataMap.size() <= 0) {
            return null;
        }
        //总能耗
        AtomicDouble sumTotalEnergy = new AtomicDouble(0.0);
        HashMap<Integer, Double> sumMap = new HashMap<>(6);
        //图表
        HashMap<String, HashMap<Integer, Double>> resultChartMap = new HashMap<>(9);
        HashMap<Integer, Double>  init = new HashMap<>(0);
        dataMap.entrySet().stream()
                .forEach(m -> {
                    if(m.getValue() == null || m.getValue().size() <= 0){
                        resultChartMap.put(m.getKey(),init);
                        return;
                    }
                    HashMap<Integer, Double> map = new HashMap<>(6);
                    m.getValue().entrySet().stream().filter(time -> time.getValue() != null && time.getValue().size() >= 2)
                            .forEach(item -> {
                                if(item.getKey()== null || item.getKey().indexOf(",") == -1){
                                    return;
                                }
                                String[] split = item.getKey().split(",");
                                if(split.length <3){
                                    return;
                                }
                                Integer key = Integer.valueOf(split[split.length -1]);
                                Double max = Collections.max(item.getValue());
                                Double min = Collections.min(item.getValue());
                                if (max == null || min == null) {
                                    return;
                                }
                                double val = max - min;
                                BigDecimal bg = new BigDecimal(val);
                                val = bg.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
                                //总能耗
                                sumTotalEnergy.addAndGet(val);
                                //累计所有分时段的值 put
                                Double aDouble = map.get(key);
                                if(aDouble == null){
                                    aDouble = 0.0;
                                }
                                aDouble+=val;
                                map.put(key, aDouble);

                                //总计存值
                                Double sumDouble = sumMap.get(key);
                                if (sumDouble == null) {
                                    sumDouble = 0.0;
                                }
                                sumDouble += val;
                                sumMap.put(key, sumDouble);
                            });
                    resultChartMap.put(m.getKey(), map);
                });
        //总计百分比
        String electric="electric",prop="prop";
        HashMap<Integer, HashMap<String, Object>> resultSumMap = new HashMap<>(4);
        sumMap.entrySet().stream().forEach(item -> {
            HashMap<String, Object> map = new HashMap<>(4);
            //电量
            map.put(electric, item.getValue());
            double val=0.0;
            if(sumTotalEnergy.get() != 0){
                val = (item.getValue() / sumTotalEnergy.get()) * 100;
            }
            BigDecimal bg = new BigDecimal(val);
            val = bg.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
            //占比
            map.put(prop,val);
            resultSumMap.put(item.getKey(), map);
        });
        //排序
        LinkedHashMap<String, HashMap<Integer, Double>> collect= null;
        if(resultChartMap != null && resultChartMap.size()>0){
            collect = resultChartMap.entrySet().stream().sorted((m1, m2) -> Long.compare(DateUtil.parse(m1.getKey(), format).getTime(), DateUtil.parse(m2.getKey(), format).getTime()))
                    .collect(Collectors.toMap(m -> m.getKey(), m -> {
                        if (m.getValue() == null || m.getValue().size() <= 0) {
                            return m.getValue();
                        }
                        return m.getValue().entrySet().stream().sorted((m1, m2) -> Integer.compare(m1.getKey(), m2.getKey())).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (k1, k2) -> k2, LinkedHashMap::new));
                    }, (key1, key2) -> key2, LinkedHashMap::new));
        }
        HashMap<String, Object> resultMap = new HashMap<>(2);
        resultMap.put("chart", collect);
        resultMap.put("ratio", resultSumMap);
        resultMap.put("total", sumTotalEnergy.get());
        return resultMap;
    }

    /***
     * 获取es保存到对象
     * @param searchResponse
     * @param resultTreeMap
     * @return
     */
    private String getEsDateAnalysis(SearchResponse searchResponse, TreeMap<Long, Double> resultTreeMap) {
        String scrollId = null;
        if (Objects.isNull(searchResponse) || !Objects.equals(searchResponse.status(), RestStatus.OK)) {
            return scrollId;
        }
        SearchHit[] hits = searchResponse.getHits().getHits();
        if (hits == null || hits.length <= 0) {
            return scrollId;
        }
        //开始数据解析
        long length = searchResponse.getHits().totalHits;
        log.info("scrollHits length=" + hits.length);
        int i = 0;
        for (SearchHit searchHit : hits) {
            String sourceAsString = searchHit.getSourceAsString();
            if (sourceAsString == null) {
                continue;
            }
            JSONObject jsonObject = JSONObject.parseObject(sourceAsString);
            if (jsonObject == null || jsonObject.size() <= 0) {
                continue;
            }
            JSONObject data = jsonObject.getJSONObject("data");
            if (data == null || data.size() <= 0) {
                continue;
            }
            //开始处理
            Double positive_active_energy = data.getDouble("positive_active_energy");
            Date createTime = jsonObject.getDate("createTime");
            if (createTime == null) {
                continue;
            }
            resultTreeMap.put(createTime.getTime(), positive_active_energy);
        }
        scrollId = searchResponse.getScrollId();
        return scrollId;
    }


    /***
     * 查询es数据
     * @param esQuerymodel
     * @param page
     * @param size
     * @param distributionElectricPriceConfigs
     * @return
     */
    public SearchResponse energyStatisticsByDeviceCodeEs(EsQuerymodel esQuerymodel, int page, int size, List<DistributionElectricPriceConfig> distributionElectricPriceConfigs) {
        if (ObjectUtils.isEmpty(esQuerymodel.getAttributeIdentifiers())
                || ObjectUtils.isEmpty(distributionElectricPriceConfigs)) {
            return null;
        }
        esQuerymodel.setQueryTimeEnd(DateUtil.getYYYYMMDDDate(esQuerymodel.getCurrentEndTime()));
        Date date = new Date();
        Calendar dateEnd = Calendar.getInstance();
        dateEnd.setTime(date);
        dateEnd.set(Calendar.HOUR_OF_DAY, 23);
        dateEnd.set(Calendar.MINUTE, 59);
        dateEnd.set(Calendar.SECOND, 59);
        date = dateEnd.getTime();
        if (date.before(esQuerymodel.getCurrentEndTime())) {
            esQuerymodel.setCurrentEndTime(date);
        }
        List<String> necessaryFieldList = esQuerymodel.getAttributeIdentifiers();
//        LinkappTenant currentTenant = linkappTenantService.currentTenant();
//        Assert.notNull(currentTenant, "当前租户为空");
//        Assert.notNull(currentTenant.getProjectId(), "当前租户项目id为空");
//        Long projectId = CommonUtils.parseLong(currentTenant.getProjectId());
        QueryBuilder boolquery = QueryBuilders.boolQuery();
        if (!CollectionUtils.isEmpty(necessaryFieldList)) {
            necessaryFieldList.forEach(item -> {
//                属性状态值 挪到了 data之下
                QueryBuilder existQuery = QueryBuilders.existsQuery("data." + item);
                ((BoolQueryBuilder) boolquery).should(existQuery);
            });
        }
        //        解决bug 【ID1003343】【设备详情】设备历史数据比设备管理平台的少一条最新的
        //index--;
        // es 6.0以上支持RestHighLevelClient
        RestHighLevelClient hclient = eSconfig.getFactory().getRhlClient();

        DateHistogramInterval dateHistogramInterval = null;
        String dateFormat = null, indices = "";
        if (esQuerymodel.getMomStatisticKind() == 4) {
            dateHistogramInterval = DateHistogramInterval.MONTH;
            dateFormat = "yyyy-MM";
            indices += "deviceflow-" + DateUtil.format(esQuerymodel.getCurrentEndTime(), "yyyy");
        } else {
            dateHistogramInterval = DateHistogramInterval.DAY;
            dateFormat = "yyyy-MM-dd";
            //        获取索引,这个月和上个月的 deviceflow-202101,deviceflow-202012
            List<String> hourByDay = OpenApiDataVService.getTimeBetween(DateUtil.format(esQuerymodel.getCurrentBeginTime(), DateUtil.yyyyMM),
                    DateUtil.format(esQuerymodel.getCurrentEndTime(), DateUtil.yyyyMM), DateUtil.yyyyMM, Calendar.MONTH);
            for (int i = 0; i < hourByDay.size(); i++) {
                indices += "deviceflow-" + hourByDay.get(i);
                if (i < (hourByDay.size() - 1)) {
                    indices += ",";
                }
            }
        }
        SearchRequest searchRequest = new SearchRequest(indices);
        //忽略不可用索引，允许索引不不存在，通配符表达式将扩展为打开的索引
        searchRequest.indicesOptions(IndicesOptions.fromOptions(true, true, true, false));
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        // 查询条件，可以参考官网手册
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        Assert.notNull(esQuerymodel.getDeviceCodeList(), "查询Es，设备编号不能为空!");
        boolQuery.must(QueryBuilders.termsQuery("deviceCode", esQuerymodel.getDeviceCodeList()));
        boolQuery.must(boolquery);

        RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("createTime").format("yyyy-MM-dd HH:mm:ss");
        if (!StringUtils.isEmpty(esQuerymodel.getCurrentBeginTime())) {
            rangeQueryBuilder.gte(DateUtil.getYYYYMMDDHHMMSSDate(esQuerymodel.getCurrentBeginTime()));
        }
        if (!StringUtils.isEmpty(esQuerymodel.getCurrentEndTime())) {
            rangeQueryBuilder.lte(DateUtil.getYYYYMMDDHHMMSSDate(esQuerymodel.getCurrentEndTime()));
        }
        boolQuery.filter(rangeQueryBuilder);
        // 组装ES请求数据
        List<DistributionElectricPriceConfigTime> configTimes = distributionElectricPriceConfigs.stream().filter(m -> !ObjectUtils.isEmpty(m.getDistributionElectricPriceConfigTimeList()))
                .flatMap(m -> m.getDistributionElectricPriceConfigTimeList().stream())
                .collect(Collectors.toList());
        if (configTimes == null || configTimes.size() <= 0) {
            return null;
        }
        StringBuffer sb = new StringBuffer();
        Long oneDayTimestamps= Long.valueOf(60*60*24*1000);
        Long dayTime=Long.valueOf(86400000);
        for (int i = 0; i < configTimes.size(); i++) {
            @NotNull LocalTime startTime = configTimes.get(i).getStartTime();
            @NotNull LocalTime endTime = configTimes.get(i).getEndTime();
            //当天时间戳
            long startLong = localTimeToLong(startTime);
            long endLong = localTimeToLong(endTime);
            //log.info("查询时间段:"+startTime+",startLong;"+"-"+endTime+","+endLong);
            //nowtime-(nowtime+60*60*8*1000)%86400000 + startLong
            sb.append(" (doc['createTime'].value.millis >=((doc['createTime'].value.millis-(doc['createTime'].value.millis)%"+dayTime+") + "+startLong+") " +
                    " && doc['createTime'].value.millis<=((doc['createTime'].value.millis-(doc['createTime'].value.millis)%"+dayTime+") + "+endLong+")) ");
//            sb.append(" (doc['createTime'].value.hourOfDay>=" + startTime.getHour());
//            sb.append(" && doc['createTime'].value.minuteOfHour>=" + startTime.getMinute());
//            sb.append(" && doc['createTime'].value.secondOfMinute>=" + startTime.getSecond());
//            sb.append(" && doc['createTime'].value.hourOfDay>=" + endTime.getHour());
//            sb.append(" && doc['createTime'].value.minuteOfHour>=" + endTime.getMinute());
//            sb.append(" && doc['createTime'].value.secondOfMinute>=" + endTime.getSecond() + ")");
            if (i < configTimes.size() - 1) {
                sb.append(" || ");
            }
        }
        QueryBuilder filterQuery = QueryBuilders.boolQuery().filter(QueryBuilders.scriptQuery(
                new Script(sb.toString())
        ));
        boolQuery.filter(filterQuery);
        searchSourceBuilder.query(boolQuery);
        String[] includeFields = new String[]{};
        String[] excludeFields = new String[]{"sourceRef"};
        searchSourceBuilder.fetchSource(includeFields, excludeFields);


        searchSourceBuilder.trackTotalHits(true);
        //        ES 本身限制 最大只能查询一万条
        Assert.isTrue(size <= 10000, "超过最大查询数，请缩小查询范围");
        searchSourceBuilder.from(page).size(size);  //取数大小
        searchSourceBuilder.sort("createTime", SortOrder.DESC); //倒叙
        searchRequest.source(searchSourceBuilder);
        long startTime = System.currentTimeMillis();
        try {
            // 查询结果
            log.info("设备数据详情ES请求数据：" + searchRequest.toString());
            SearchResponse searchResponse = hclient.search(searchRequest, RequestOptions.DEFAULT);
            long sysEndTime = System.currentTimeMillis();
            log.info("查询用时:" + (sysEndTime - startTime));
            if (searchResponse == null) {
                return null;
            }
            return searchResponse;
        } catch (Exception e) {
            log.error("搜索ES数据,索引:" + esQuerymodel.getDeviceCodeList() + "异常:{}", e.getStackTrace());
            log.error("搜索ES数据,索引:" + esQuerymodel.getDeviceCodeList() + "异常:{}", e.getMessage());
            e.printStackTrace();
            return null;
        }
    }

    private long localTimeToLong(LocalTime startTime){
        int hour = startTime.getHour();
        int second = startTime.getSecond();
        int minute = startTime.getMinute();
        int mi=1000;
        return (hour * 3600 * mi) + (second * 60 * mi) + (minute * mi);
    }


    /***
     * 补齐天
     * @param hourCollect
     * @param startHour
     * @param endHour
     * @return
     */
    public static void getHourConllect(HashMap<String, HashMap<String, List<Double>>> hourCollect,Date startHour, Date endHour,String format) {
        List<String> hourByDay = OpenApiDataVService.getTimeBetween(DateUtil.format(startHour, format), DateUtil.format(endHour, format), format, Calendar.DAY_OF_MONTH);
        HashMap<String, List<Double>> initMap = new HashMap<>(0);
        for (int i = 0; i < hourByDay.size(); i++) {
            String day = hourByDay.get(i);
            HashMap dataMap = hourCollect.get(day);
            if (dataMap != null) {
                continue;
            }
            dataMap = initMap;
            hourCollect.put(day, dataMap);
        }
        return;
    }
}
